﻿#pragma once

#include "../../MirObjects/Effect.h"
#include "../../MirControls/MirImageControl.h"
#include "../../MirControls/MirButton.h"
#include "../../MirControls/MirLabel.h"
#include "../../Settings.h"
#include "../../../Shared/Enums.h"
#include "../../../Shared/Data/ItemData.h"
#include "../../MirControls/MirGoodsCell.h"
#include "../../MirControls/MirItemCell.h"
#include "../../MirControls/MirDropDownBox.h"
#include "../../../Shared/Data/ClientData.h"
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <cmath>
#include <limits>
#include <any>
#include "../../../bankersrounding.h"
#include "../../../stringhelper.h"

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirObjects;
using namespace Client::MirSounds;
//C# TO C++ CONVERTER TODO TASK: C# to C++ Converter could not confirm whether this is a namespace alias or a type alias:
//using Font = System::Drawing::Font;
namespace S = ServerPackets;
namespace C = ClientPackets;

using namespace Client::MirScenes::Dialogs;

namespace Client::MirScenes::Dialogs
{
    class NPCDialog final : public MirImageControl
    {
    public:
        static Regex *R;
        static Regex *C;
        static Regex *L;

        MirButton *CloseButton, *UpButton, *DownButton, *PositionBar, *QuestButton;
        std::vector<MirLabel*> TextLabel;
        std::vector<MirLabel*> TextButtons;

        MirLabel *NameLabel;

    private:
        System::Drawing::Font *font = new System::Drawing::Font(Settings::FontName, 9.0F);

    public:
        std::vector<std::string> CurrentLines = std::vector<std::string>();
    private:
        int _index = 0;
    public:
        int MaximumLines = 8;

        virtual ~NPCDialog()
        {
            delete CloseButton;
            delete UpButton;
            delete DownButton;
            delete PositionBar;
            delete QuestButton;
            delete NameLabel;
            delete font;
        }

        NPCDialog();

    private:
        void NPCDialog_MouseWheel(std::any sender, MouseEventArgs *e);

        void PositionBar_OnMoving(std::any sender, MouseEventArgs *e);

        void UpdatePositionBar();


    public:
        void NewText(std::vector<std::string> &lines, bool resetIndex = true);

    private:
        void NewButton(const std::string &text, const std::string &key, Point *p, const std::string &link = "");

        void NewColour(const std::string &text, const std::string &colour, Point *p);

    public:
        void CheckQuestButtonDisplay();

        void Hide() override;

        void Show() override;
    };
    class NPCGoodsDialog final : public MirImageControl
    {
    public:
        PanelType PType = static_cast<PanelType>(0);
        bool UsePearls = false;

        int StartIndex = 0;
        UserItem *SelectedItem;

        std::vector<UserItem*> Goods = std::vector<UserItem*>();
        std::vector<UserItem*> DisplayGoods = std::vector<UserItem*>();
        std::vector<MirGoodsCell*> Cells;
        MirButton *BuyButton, *CloseButton;
        MirImageControl *BuyLabel;

        MirButton *UpButton, *DownButton, *PositionBar;

        virtual ~NPCGoodsDialog()
        {
            delete SelectedItem;
            delete BuyButton;
            delete CloseButton;
            delete BuyLabel;
            delete UpButton;
            delete DownButton;
            delete PositionBar;
        }

        NPCGoodsDialog(PanelType type);

    private:
        bool CheckSubGoods();

        void BuyItem();

        void NPCGoodsPanel_MouseWheel(std::any sender, MouseEventArgs *e);
        void Update();

        void PositionBar_OnMoving(std::any sender, MouseEventArgs *e);

    public:
        void NewGoods(std::vector<UserItem*> &list);

        void Hide() override;

        void Show() override;
    };

    class NPCDropDialog final : public MirImageControl
    {

    public:
        MirButton *const ConfirmButton, *const HoldButton;
        MirItemCell *const ItemCell;
        MirItemCell *OldCell;
        MirLabel *const InfoLabel;
        PanelType PType = static_cast<PanelType>(0);

        static UserItem *TargetItem;
        bool Hold = false;


        virtual ~NPCDropDialog()
        {
            delete ConfirmButton;
            delete HoldButton;
            delete ItemCell;
            delete OldCell;
            delete InfoLabel;
        }

        NPCDropDialog();

    private:
        void NPCDropPanel_AfterDraw(std::any sender, EventArgs *e);

        void NPCDropPanel_Click(std::any sender, EventArgs *e);

        void Confirm();

        void ItemCell_Click();

        void NPCDropPanel_BeforeDraw(std::any sender, EventArgs *e);

    public:
        void Hide() override;
        void Show() override;
    };
    class NPCAwakeDialog final : public MirImageControl
    {

    public:
        MirButton *UpgradeButton, *CloseButton;
        std::vector<MirItemCell*> ItemCells = std::vector<MirItemCell*>(7);
        MirDropDownBox *SelectAwakeType;
        AwakeType CurrentAwakeType = AwakeType::None;
        MirLabel *GoldLabel, *NeedItemLabel1, *NeedItemLabel2;

        static std::vector<UserItem*> Items;
        static std::vector<int> ItemsIdx;

        virtual ~NPCAwakeDialog()
        {
            delete UpgradeButton;
            delete CloseButton;
            delete SelectAwakeType;
            delete GoldLabel;
            delete NeedItemLabel1;
            delete NeedItemLabel2;
        }

        NPCAwakeDialog();

        void ItemCellClear();

        void ItemCell_Click();

        std::string getAwakeTypeText(AwakeType type);

        AwakeType getAwakeType(const std::string &typeName);

        void OnAwakeTypeSelect(int Index);

        void setNeedItems(std::vector<ItemInfo*> &Materials, std::vector<unsigned char> &MaterialsCount);

        bool CheckNeedMaterials();

        void Awakening();

        void Hide() override;

        void Show() override;
    };


    class CraftDialog final : public MirImageControl
    {
    public:
        UserItem *RecipeItem;
        ClientRecipeInfo *Recipe;

    private:
        static constexpr int _toolCount = 3;
        static constexpr int _ingredientCount = 6;
    public:
        virtual ~CraftDialog()
        {
            delete RecipeItem;
            delete Recipe;
            delete CraftButton;
            delete AutoFillButton;
            delete CloseButton;
            delete RecipeLabel;
            delete PossibilityLabel;
            delete GoldLabel;
        }

    private:
        static int getTotalCount();

    public:
        static std::vector<UserItem*> Slots;
        static std::vector<UserItem*> ShadowItems;

        std::unordered_map<MirItemCell*, unsigned long long> Selected = std::unordered_map<MirItemCell*, unsigned long long>();

        std::vector<MirItemCell*> Grid;

        MirButton *CraftButton, *AutoFillButton, *CloseButton;

        MirLabel *RecipeLabel;
        MirLabel *PossibilityLabel;
        MirLabel *GoldLabel;

        CraftDialog();

    private:
        void CraftDialog_BeforeDraw(std::any sender, EventArgs *e);

        void Grid_Click(std::any sender, EventArgs *e);

    public:
        void Hide() override;

        void Show() override;

    private:
        void AutoFill();

        void CraftItem();

        bool HasCraftItems(unsigned short count);

    public:
        void ResetCells(bool clearRecipe = true);

        MirItemCell *GetCell(unsigned long long id);

        void UpdateCraftCells();

        void RefreshCraftCells(UserItem *selectedItem);
    };
    class RefineDialog final : public MirImageControl
    {
    public:
        std::vector<MirItemCell*> Grid;
        MirButton *RefineButton;

        virtual ~RefineDialog()
        {
            delete RefineButton;
        }

        RefineDialog();

        void Hide() override;

        void RefineCancel();

        void RefineReset();



        MirItemCell *GetCell(unsigned long long id);

    };
    class StorageDialog final : public MirImageControl
    {
    public:
        std::vector<MirItemCell*> Grid;
        MirButton *Storage1Button, *Storage2Button, *RentButton, *ProtectButton, *CloseButton;
        MirImageControl *LockedPage;
        MirLabel *RentalLabel;

        virtual ~StorageDialog()
        {
            delete Storage1Button;
            delete Storage2Button;
            delete RentButton;
            delete ProtectButton;
            delete CloseButton;
            delete LockedPage;
            delete RentalLabel;
        }

        StorageDialog();

        void Show() override;

        void RefreshStorage1();

        void RefreshStorage2();

        MirItemCell *GetCell(unsigned long long id);
    };
}
